#ifndef TC_CHAIKINMONEYFLOW_HPP
#define TC_CHAIKINMONEYFLOW_HPP

/** \file ChaikinMoneyFlow.hpp
 * Definition of the function template ChaikinMoneyFlow.
 *
 * (C) Copyright 2003-2006 by Semih Cemiloglu
 * All rights reserved, see COPYRIGHT file for details.
 *
 * $Id: ChaikinMoneyFlow.hpp 110 2006-06-19 03:38:33Z semihc $
 *
 *
 */


#include "TA.hh"
#include "CircArray.hpp"

namespace TC {

  //! On Balance Volume function
  TC_EXPORT template <typename InputIterator,
                      typename OutputIterator,
                      class Adaptor>
  void ChaikinMoneyFlow(InputIterator fromPos,
			InputIterator fromEnd,
			OutputIterator toPos,
			const unsigned period,
			const Adaptor adaptor)
  {
    TC_PRE_CONDITION(period > 0);

    // Chaikin Money Flow value
    register TAfp_t cmf = 0.0;
    // Accumulation/Distribution value
    register TAfp_t ad = 0.0;
    // AD array
    CircArray<TAfp_t> ad_array(period);
    // Volume array
    CircArray<TAfp_t> vol_array(period);

    typename Adaptor::Price_t cls, hi, lo;
    typename Adaptor::Volume_t vol;

    for(; fromPos!=fromEnd; ++fromPos) {
      cls = adaptor.cls(*fromPos);
      vol = adaptor.vol(*fromPos);
      hi = adaptor.hi(*fromPos);
      lo = adaptor.lo(*fromPos);
      // Calculate accumulation distribution value
      ad = (((cls-lo)-(hi-cls))/(hi-lo))* vol;

      ad_array.push(ad);
      vol_array.push(vol);
      cmf = ad_array.sum() / vol_array.sum();

      // Store the CMF value
      *toPos++ = cmf;
    } // end for

  }

} // end namespace


#endif /* Include guard */
